#include "../include/device_pthread.h"
#include "../include/list_queue.h"
#include "../include/msg.h"
#include "../include/mysqlite.h"
#include "../include/device_pthread.h"
#include "../include/myjson.h"

/**
 * 设备端对接文件，设备端所有的用户名和密码是一致的，不同的只有设备号，且是唯一的
 */

/**
 * 设备登录JSON用例
 * {"ID":"11","PW":"1111111","cmd":0,"devNo":"11","flag":0,"msgType":0}
 */

/**
 * 设备端登录函数
 * 0 成功  -1 失败 需要再次接收登录消息；
 */
int device_login_manage(list_t *clinode, msg_t *clientmsg)
{
    int ret;
    clientmsg->flags = 1;
    char send_json_buf[128] = {0};

    if (clientmsg->cmd == PCCLIENT_LOGIN) // 登录
    {
        // 遍历链表中是否有对应的的节点存在，有则已经登录成功，拒绝登录
        // 设备端只有设备号不同，所以使用设备号遍历
        ret = list_find_devnum(get_device_list_head(), clientmsg->device_id);
        if (ret == 0)
        {
            clientmsg->flags = 0;
            set_infomsg_err("The user has already logged in.");
        }
    }
    else
    {
        // 首条消息非登录信息 打回，关闭
        clientmsg->flags = 0;
        set_infomsg_err("The msg is not login.");
    }

send_json:
    // 开始封装json
    if (clientmsg->flags == 0)
        sprintf(send_json_buf, "{\"flag\":%d,\"buf\":\"%s\"}", clientmsg->flags, get_infomsg_err());
    else
        sprintf(send_json_buf, "{\"flag\":%d,\"buf\":\"\"}", clientmsg->flags);

    if ((ret = send(clinode->client_sockfd, send_json_buf, strlen(send_json_buf), 0)) == -1)
    {
        ERR_PRIENT("send error");
        return -1;
    }

    return clientmsg->flags == 1 ? 0 : -1;
}

/**
 * 设备端处理函数 接收消息队列消息，发送给dev设备，接收dev设备的消息，重新插入到消息队列
 */
int device_msg_handle(list_t *clinode, msg_t *clientmsg)
{
    int ret;
    printf("开启循环等待处理\n");
    msg_queue_t devmsgq;

    memset(&devmsgq, 0, sizeof(msg_queue_t));
    for (int i = 0; i < strlen(clientmsg->device_id); i++)
    {
        devmsgq.msgtype += clientmsg->device_id[i];
    }

    // 不再需要等待socket的数据，但是需要等待消息队列的对应设备号类型的消息
    while (1)
    {
        // 等待消息队列消息 qt_to_dev
        memset(devmsgq.jsonbuf, 0, sizeof(devmsgq.jsonbuf));
        ret = msg_recv_to_queue(get_qtod_queue(), &devmsgq, devmsgq.msgtype);
        if(ret == -1)
        {
            ERR_LOG("msg_recv_to_queue error");
        }
            

        printf("device recv %ld %s\n", devmsgq.msgtype, devmsgq.jsonbuf);

        // 不需要解析，直接将json发送给设备
        ret = send(clinode->client_sockfd, devmsgq.jsonbuf, strlen(devmsgq.jsonbuf), 0);
        if (ret <= 0)
        {
            ERR_LOG("send to dev error");
        }

        memset(devmsgq.jsonbuf, 0, sizeof(devmsgq.jsonbuf));
        // 等待设备回复信息 同样不需要解析
        ret = recv(clinode->client_sockfd, devmsgq.jsonbuf, sizeof(devmsgq.jsonbuf), 0);
        if (ret <= 0)
        {
            ERR_LOG("recv from dev error");
        }

        // 判断接收到的是否是json
        if (is_valid_json(devmsgq.jsonbuf) != 0)
        {
            char buf[64] = {0};
            sprintf(buf, "{\"flag\":0,\"buf\":\"The data is not in JSON format.\"}");
            ret = send(clinode->client_sockfd, buf, strlen(buf), 0);
            if (ret <= 0)
            {
                ERR_LOG("send to dev error");
            }
            continue; // 结束此次循环，不结束接收消息
        }

        // 将设备回复json转换为消息队列 放在dev_to_qt
        if (msg_send_to_queue(get_dtoq_queue(), &devmsgq) == -1)
            return -1;

        printf("device send %ld %s\n", devmsgq.msgtype, devmsgq.jsonbuf);
    }

    return 0;
}
